/*
*   ProcessADT.c
*   Authors: Dustin Striplin
*   contains all of the information pertinant to a process
*   5 types of processes:
*                           compute bound(does not require io)
*                           io bound- makes a request for io service periodically, only one per io device.
*                           keyboard process - waits for keyboard device
*                           producer - calculates a number & stores it in shared memory (uses cond. vars & mutexes)
*                           consumer - reads value when signaled & prints it to console(uses cond. vars & mutexes)
*                                               use sample program #5 for producer consumer
*/

#include <stdio.h>
#include <stdlib.h>

#include "ProcessADT.h"


/*
*   Create a new ProcessADT
*   parameters:
*               proc_type, the type of process
*               no_steps,  the number of steps the process runs before a request is made
*               no_requests,  the number of requests to make (should be equal to length of requests)
*               requests,    the requests to make, consider this a pseudo program
*/
ProcessPtr processConstructor(int proc_type, int no_steps, int no_requests, RequestPtr* requests) {    //TODO NEEDS ACCESS TO PTHREAD MUTEX AND CONDITION VARIABLE.
    ProcessPtr toReturn = (ProcessPtr) malloc(sizeof(ProcessStr));
    toReturn->proc_type = proc_type;
    toReturn->no_steps = no_steps;
    toReturn->pc = 0;
    toReturn->no_requests = no_requests;
    toReturn->request_index = 0;
    toReturn->requests = requests;
    toReturn->destruct = processDestructor;
    toReturn->step = processStep;

    return toReturn;
}

/*
*   free memory from heap
*/
void processDestructor(ProcessPtr theProcess) {
    free(theProcess);
}


/*
* next instruction is executed. After the predetermined number of steps have run
*   the next request will be executed.
*   returns: the request, if there is no request then NULL is returned.
*/
RequestPtr processStep(ProcessPtr this) {
    this->pc++;

    if(this->pc == this->no_steps) {
        this->pc = 0;
        if(this->no_requests > this->request_index)  //if there are still requests to send
            return this->requests[this->request_index++];//return requests & increment request_index
    }
    return (RequestPtr)NULL;
}

/*
int main() {

    printf("Hello from ProcessADT\n");
    int no_requests = 10;
    RequestPtr* requests = (RequestPtr*) malloc(sizeof(RequestPtr) * no_requests); //create an array
    int i = 0;
    for(;i<no_requests;i++) {
        requests[i] = requestConstructor(i,i*2);
    }

    printf("objects created\n");

    ProcessPtr testProcess = processConstructor(COMPUTE, 10, no_requests, requests);

    while(testProcess->no_requests > testProcess->request_index) {
        RequestPtr request = testProcess->step(testProcess);
        if(request != (RequestPtr) NULL) {
            printf("RequestType = %d, ID = %d\n", request->requestType, request->objectID);
        }
    }

    i = 0;
    for(;i<no_requests;i++) {
        requests[i]->destruct(requests[i]);
    }

    free(requests);

    testProcess->destruct(testProcess);

    printf("objects deleted\n");
}
*/
